import re

from django.conf import settings
from django.core.mail import send_mail
from django_redis import get_redis_connection
from rest_framework import serializers
from rest_framework_jwt.settings import api_settings
from celery_tasks.email.tasks import send_verify_email
# from celery_tasks.email.tasks import send_email
from itsdangerous import TimedJSONWebSignatureSerializer as TJS

from goods.models import SKU
from users.models import User, Address


class CreateUserSerializer(serializers.ModelSerializer):
    """
    创建用户序列化器
    """
    password2 = serializers.CharField(label='确认密码', write_only=True)
    sms_code = serializers.CharField(label='短信验证码', write_only=True)
    allow = serializers.CharField(label='同意协议', write_only=True)

    # 增加ｔｏｋｅｎ字段
    token = serializers.CharField(label='登入状态token', read_only=True)

    class Meta:
        model = User

        fields = ('token', 'id', 'username', 'password', 'password2', 'mobile', 'sms_code', 'allow')

        extra_kwargs = {
            'username': {
                "min_length": 5,
                "max_length": 20,
                "error_messages": {
                    "min_length": '仅允许５－２０个字符之间的用户名',
                    "max_length": '仅允许５－２０个字符之间的用户名',
                },
            },
            'password': {
                "min_length": 8,
                "max_length": 20,
                "error_messages": {
                    "min_length": '仅允许５－２０个字符之间的密码',
                    "max_length": '仅允许５－２０个字符之间的密码',
                },
            },
        }

    def validate_mobile(self, value):
        """
        验证手机号
        """
        if not re.match(r'^1[3-9]\d{9}$', value):
            raise serializers.ValidationError('手机格式错误')
            # return serializers.ValidationError('手机格式错误')
        return value

    def validate_allow(self, value):
        """
        检查用户是否同意协议
        :param value:
        :return:
        """
        if value != 'true':
            raise serializers.ValidationError('请同意用户协议［你不同意也没法注册］')
            # return serializers.ValidationError('请同意用户协议［你不同意也没法注册］')
        return value

    def validate(self, data):
            """
            判断两次密码是否一致
            :param data:
            :return:
            """
            if data['password'] != data['password2']:
                raise serializers.ValidationError('两次密码不一致')
                # return serializers.ValidationError('两次密码不一致')

            # 判读短信验证码
            redis_conn = get_redis_connection('verify')

            mobile = data['mobile']

            real_sms_code = redis_conn.get('sms_code_%s' % mobile)

            if real_sms_code is None:
                raise serializers.ValidationError('短信验证码已过期')
                # return serializers.ValidationError('短信验证码已过期')

            if data['sms_code'] != real_sms_code.decode():
                raise serializers.ValidationError('短信验证码错误．请核对验证码')
                # return serializers.ValidationError('短信验证码错误．请核对验证码')

            return data

    def create(self, validated_data):

        del validated_data['password2']
        del validated_data['sms_code']
        del validated_data['allow']

        user = super().create(validated_data)

        user.set_password(validated_data['password'])

        user.save()

        # 补充生成记录登入状态的ｔｏｋｅｎ
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER

        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)

        token = jwt_encode_handler(payload)

        user.token = token

        return user


class UserDetailSerializer(serializers.ModelSerializer):
    """
    用户详细信息序列化器
    """
    class Meta:
        model = User
        fields = ('id', "username", 'mobile', 'email', 'email_active')


class EmailSerializer(serializers.ModelSerializer):
    """
    邮箱序列化器
    """
    class Meta:
        model = User
        fields = ('id', 'email')
        extra_kwargs = {
            'email': {
                'required': True
            }
        }

    def update(self, instance, validated_data):
        # 获取验证后的ｅｍａｉｌ
        # instance.email = validated_data['email']
        email = validated_data['email']

        # 通过ｃｏｎｔｅｘｔ获取ｒｅｑｕｅｓｔ对象
        user = self.context['request'].user

        # 更新当前用户的ｅｍａｉｌ数据
        # user.email = instance.email
        user.email = email

        user.save()
        # instance.save()

        data = {'id': user.id, 'username': user.username}

        # 加密用户数据
        tjs = TJS(settings.SECRET_KEY, 300)
        token = tjs.dumps(data).decode()
        verify_url = 'http://www.meiduo.site:8080/success_verify_email.html?token=' + token

        # 发送邮件
        # send_mail('美多商城验证', '', settings.EMAIL_FROM, ['2665704162@qq.com'], html_message='<a href="www.baidu.com">百度</a>')
        # send_verify_email.delay(email, verify_url)
        send_verify_email.delay(email, verify_url)

        return user
        # return instance

# import re
# from rest_framework import serializers
# from users.models import User
# from django_redis import get_redis_connection
#
# '''
# username	str	是	用户名
# password	str	是	密码
# password2	str	是	确认密码
# sms_code	str	是	短信验证码
# mobile	str	是	手机号
# allow	str	是	是否同意用户协议
#
# '''
#
#
# class UserSerializer(serializers.ModelSerializer):
#     # 额外到字段验证需要显示指明
#     password2 = serializers.CharField(max_length=20, min_length=8, write_only=True)
#     sms_code = serializers.CharField(max_length=6, min_length=6, write_only=True)
#     allow = serializers.CharField(write_only=True)
#
    # # 增加ｔｏｋｅｎ字段
    # token = serializers.CharField(label='登入状态token', read_only=True)
    #
    # class Meta:
    #     model = User
    #     fields = ('token', 'id', 'username', 'mobile', 'password', 'password2', 'sms_code', 'allow')
    #     # 对于模型类字段进行额外限制条件添加
    #     extra_kwargs = {
    #         'username': {
    #             'max_length': 20,
    #             'min_length': 5,
    #             'error_messages': {
    #                 'max_length': '名字过长',
    #                 'min_length': '名字过短'
    #             }
    #         },
    #         'password': {
    #             'write_only': True,
    #             'max_length': 20,
    #             'min_length': 8,
    #             'error_messages': {
    #                 'max_length': '密码过长',
    #                 'min_length': '密码过短'
    #             }
    #         }
    #
    #     }
    #
    # 手机号验证
    # def validate_mobile(self, value):
    #
    #     print(value)
    #
    #     if not re.match(r'^1[3-9]\d{9}$', value):
    #         return serializers.ValidationError('手机号不正确')
    #
    #     return value
    #
    # # 选中状态
    # def validate_allow(self, value):
    #
    #     if value != 'true':
    #         return serializers.ValidationError('状态未选中')
    #
    #     return value
    #
    # def validate(self, attrs):
    #     # 密码判断
    #     if attrs['password'] != attrs['password2']:
    #         return serializers.ValidationError('密码不一致')
    #
    #     # 短信验证
    #     # 从缓存中取出短息
    #     conn = get_redis_connection('verify')
    #     sms_code_real = conn.get('sms_code_%s' % attrs['mobile'])
    #     # 获取不到短信
    #     if not sms_code_real:
    #         return serializers.ValidationError('短信失效')
    #
    #     if attrs['sms_code'] != sms_code_real.decode():
    #         return serializers.ValidationError('短信不一致')
    #
    #     return attrs
    #
    # def create(self, validated_data):
    #
    #     print(validated_data)
    #     # 删除不需要保存的字段数据
    #     del validated_data['password2']
    #     del validated_data['sms_code']
    #     del validated_data['allow']
    #
    #     user=super().create(validated_data)
    #     # 对于明文密码加密
    #     user.set_password(validated_data['password'])
    #     user.save()
    #
    #     # 补充生成记录登入状态的ｔｏｋｅｎ
    #     jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
    #
    #     jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
    #
    #     payload = jwt_payload_handler(user)
    #
    #     token = jwt_encode_handler(payload)
    #
    #     return user


class UserAddressSerializer(serializers.ModelSerializer):
    """
    用户地址序列化器
    """
    province = serializers.StringRelatedField(read_only=True)
    city = serializers.StringRelatedField(read_only=True)
    district = serializers.StringRelatedField(read_only=True)
    province_id = serializers.IntegerField(label='省ID', required=True)
    city_id = serializers.IntegerField(label='市ID', required=True)
    district_id = serializers.IntegerField(label='区ID', required=True)

    class Meta:
        model = Address
        exclude = ('user', 'is_deleted', 'create_time', 'update_time')

    def validate_mobile(self, value):
        """
        验证手机号
        :param value:
        :return:
        """
        if not re.match(r'^1[3-9]\d{9}$', value):
            raise serializers.ValidationError('手机号格式错误')
        return value

    def create(self, validated_data):
        """
        保存地址
        :param validated_data:
        :return:
        """
        validated_data['user'] = self.context['request'].user
        return super(UserAddressSerializer, self).create(validated_data)


# class UserAddressSerializer(serializers.ModelSerializer):
#     """
#     用户地址序列化器
#     """
#     province = serializers.StringRelatedField(read_only=True)
#     city = serializers.StringRelatedField(read_only=True)
#     district = serializers.StringRelatedField(read_only=True)
#     province_id = serializers.IntegerField(label='省ID', required=True)
#     city_id = serializers.IntegerField(label='市ID', required=True)
#     district_id = serializers.IntegerField(label='区ID', required=True)
#
#     class Meta:
#         model = Address
#         exclude = ('user', 'is_deleted', 'create_time', 'update_time')
#
#     def validate_mobile(self, value):
#         """
#         验证手机号
#         """
#         if not re.match(r'^1[3-9]\d{9}$', value):
#             raise serializers.ValidationError('手机号格式错误')
#         return value
#
#     def create(self, validated_data):
#         """
#         保存
#         """
#         validated_data['user'] = self.context['request'].user
#         return super().create(validated_data)


class AddressTitleSerializer(serializers.ModelSerializer):
    """
    地址标题
    """
    class Meta:
        model = Address
        fields = ('title',)


class AddUserBrowsingHistorySerializer(serializers.Serializer):

    sku_id = serializers.IntegerField(min_value=1)

#     验证ｓｋｕ＿ｉｄ
    def validate(self, attrs):
        try:
            SKU.objects.get(id=attrs['sku_id'])
        except:
            raise serializers.ValidationError('商品不存在')

        return attrs

#     保存
    def create(self, validated_data):
        # 获取用户
        user = self.context['request'].user

        sku_id = validated_data['sku_id']

        # 建立链接
        conn = get_redis_connection('history')
        pl = conn.pipeline()
        # 重复数据删除
        pl.lrem('history_%s' % user.id, 0, sku_id)

        # 写入数据
        pl.lpush('history_%s' % user.id, sku_id)

        # 写入数量控制
        pl.ltrim('history_%s' % user.id, 0, 9)

        pl.execute()

        return validated_data
# class AddressTitleSerializer(serializers.ModelSerializer):
#     """
#     地址标题
#     """
#     class Meta:
#         model = Address
#         fields = ('title',)
